/*
*  camera calibration
*  stefanix - helloworld@stefnix.net
*/  

#include "testApp.h"


void testApp::setup() {
	screenoffset = 1000;
	screenoffsetoffset=0;
	screenoffsetoffsetDirection = -1;
    ofSetVerticalSync( true );
    ofSetWindowPosition(1920-screenoffset,0 );
    csize = cvSize( 800,600 );
	pause = false;
	camHandler.init(csize);
	
	colors = colorHandler();

	//camHandler.callibrate();
	//bufferImage.allocate(csize.width,csize.height);
	//ofbufferImage.allocate(csize.width,csize.height,OF_IMAGE_COLOR);
	pause = false;
	drawDebugBlobs = false;
	drawDebugMinMaxBlobs = false;
	
	debugBlob = ofPoint(0, 0);
	Game = new pong(&camHandler,&colors);
	startPongGame();
	ofSetCircleResolution(32);
	ofEnableAlphaBlending();
	ofEnableSmoothing();
	shakeimage = false;
	showgrid = false;
	light = 1;
}

void testApp::startPongGame()
{
	
	Game->stopGame();

	Game = new pong(&camHandler,&colors);
}
void testApp::startOOGame()
{
	Game->stopGame();

	Game = new o_o(&camHandler,&colors);
}
void testApp::pauseGame()
{
	pause = true;
}
void testApp::resumeGame()
{
	pause = false;
}
void testApp::resetGame()
{
	Game->resetGame();
}

void testApp::update() 
{
	if(!pause)
	{
		//camHandler.bufferImage = bufferImage;
		camHandler.update();

		ofCvTrackedBlob a = ofCvTrackedBlob();
		a.center = debugBlob;
		//camHandler.trackedBlobs.push_back(a);

		ofCvTrackedBlob b = ofCvTrackedBlob();
		b.center = ofPoint(debugBlob.x-50,debugBlob.y-50);
		//camHandler.trackedBlobs.push_back(b);

		ofCvTrackedBlob c = ofCvTrackedBlob();
		c.center = ofPoint(debugBlob.x+50,debugBlob.y-50);
		//camHandler.trackedBlobs.push_back(c);

		if(Game)
			Game->update();
	}

	if(screenoffsetoffset<-3)
		screenoffsetoffsetDirection = 1;
	else if(screenoffsetoffset>3)
		screenoffsetoffsetDirection = -1;

	screenoffsetoffset +=screenoffsetoffsetDirection;

}



void testApp::draw() {
	//camHandler.backgroundTexture.swapIn();
	
	int offset = screenoffset;
	if(shakeimage)
		offset+=screenoffsetoffset;

		ofSetColor(colors.backgroundcolor);

		ofFill();
		ofRect(screenoffset,0,csize.width+offset,csize.height);
		
		//White for drawing camera images
		ofSetColor(0xffffff);
	
		camHandler.colorImg.draw(0,0,200,200);
	
		camHandler.grayDiff.draw(220,0,200,200);
	
		camHandler.grayBg.draw(440,0,200,200);
	
		camHandler.grayImage.draw(660,0,200,200);
		
		ofNoFill();

		if(showgrid)
		{
			//draw grid
			ofSetColor(colors.foregroundcolor);
			int gridsize = 50;
			//y
			for(int i = 0;i<gridsize;i++)
			{
				ofLine(offset,(csize.height/gridsize)*i,offset+csize.width,(csize.height/gridsize)*i);
			}
			for(int i = 0;i<gridsize;i++)
			{
				ofLine(offset+(csize.width/gridsize)*i,0,offset+(csize.width/gridsize)*i,csize.height);
			}

		}
	
	ofRect(offset+6, 0, csize.width-12, csize.height);
	ofRect(offset+8, 2, csize.width-16, csize.height-4);
	

		Game->draw(offset);
		

		
	//}
	
	
	//
    /*if( bUndistortLiveFeed ) {
        undistortedImg.draw( 0,0, 1024,768 );
    }*/
    
    
   /* if( calib.colorImages.size() > shotToShow ) {
        drawImage( calib.colorImages[shotToShow], 20,280, 320,240 );
    }

    if( calib.undistortedImg.size() > shotToShow ) {    
        drawImage( calib.undistortedImg[shotToShow], 360,280, 320,240 );
    }*/
    
	
    // REPORT
    ofSetColor( 0xffffff );    
    ostringstream docstring;
	docstring   << "== Debug Info ==" << endl
				<< "Framerate: " << ofGetFrameRate() << endl
				<< "Tracked Blobs: " << camHandler.trackedBlobs.size() << endl
				<< "All Blobs: " << camHandler.contourFinder.blobs.size() << endl
				

				<< "== Options ==: " << endl
				<< "Pause/Unpause game: Press P |value: " << pause << endl
				<< "Draw debug blobs in bottom right corner: Press D |value: " << drawDebugBlobs << endl
				<< "Draw min/max blobs in bottom right corner: Press B |value: " << drawDebugMinMaxBlobs << endl
				<< "Adjust threshold: +/- for up and down | vlaue: " << camHandler.defaultThreshold << endl
				<< "Adjust min blob size: k/l for up and down | value: " << camHandler.minBlobSize << endl
				<< "Adjust max blob size: h/j for up and down | value: " << camHandler.maxBlobSize << endl
				<< "Subtract background: Press P" << endl
				<< "Start auto callibration (requires good lightning): Press A" << endl
				<< "Start manual callibration: Press C" << endl
				<< "Video settings: Press S" << endl;
				
				
             
    ofDrawBitmapString( docstring.str(), 10,220 );  

	if(drawDebugMinMaxBlobs || drawDebugBlobs) //Draw gray image in left right corner
	{
		camHandler.grayImage.draw(screenoffset/2,csize.height/2);
	}
	if(drawDebugMinMaxBlobs)
	{
		ofNoFill();
		ofSetColor(0xFF0000);
		// min blob
		ofCircle(screenoffset/1.5 , csize.height/1.5 , sqrt(camHandler.minBlobSize/PI));
		//max blob
		ofCircle(screenoffset/1.5 , csize.height/1.5 , sqrt(camHandler.maxBlobSize/PI));
	}
	// DRAW DEBUG BLOBS ON IMAGE
	if(drawDebugBlobs) {
		
		ofSetColor(255,0,0);
		
		// or, instead we can draw each blob individually,
		// this is how to get access to them:
		//contourFinder.draw(cwidth,cheight);
		
			
			ofNoFill();
			//ofCircle(camHandler.trackedBlobs[i].center.x,camHandler.trackedBlobs[i].center.y,50);
			ostringstream blobstring;

			//blobstring <<  time (NULL)-camHandler.trackedBlobs[i].firstseen << endl;
			//ofDrawBitmapString(  blobstring.str(), screenoffset/2 + camHandler.trackedBlobs[i].center.x,csize.height + camHandler.trackedBlobs[i].center.y-20 ); 

			camHandler.blobTracker.draw(screenoffset/2,csize.height/2);
		
	}
	//camHandler.grayImage.draw(200,200,400,300);
	//camHandler.backgroundTexture.saveImage();
	//camHandler.backgroundTexture.swapOut();
	//camHandler.backgroundTexture.draw(0,0);
	//camHandler.backgroundTexture.draw(500,500,100,100);
	//camHandler.backgroundTexture.imageSaver.draw(200,200,100,100);
	//ofbufferImage.grabScreen(0,0,csize.width,csize.height);
	//bufferImage.setFromPixels(ofbufferImage.getPixels(),csize.width,csize.height);
	//bufferImage.blur(21);
	//ofbufferImage
	
	
	if(camHandler.isCalibrating && !camHandler.isManualCalibrating)
	{
		ofFill();
		ofSetColor(0, 0, 0);
		ofRect(screenoffset, 0, csize.width, csize.height);
		
		
		ofFill();
		ofSetColor(255, 255, 255);
		
		float wratio = (float)camHandler.origsize.width/(float)camHandler.size.width;
		float hratio = (float)camHandler.origsize.height/(float)camHandler.size.height;

		
		int calibpointsize = 50;
		for(int i = 0;i < 4;i++) {
			ofRect(screenoffset+camHandler.screenpoints[i].x*wratio-(calibpointsize/2), camHandler.screenpoints[i].y*hratio-(calibpointsize/2), calibpointsize, calibpointsize);
		}
	}
	else if(camHandler.isManualCalibrating)
	{
		ofFill();
		ofSetColor(0, 0, 0);
		ofRect(screenoffset, 0, csize.width, csize.height);
		
		
		ofFill();
		
		float wratio = (float)camHandler.origsize.width/(float)camHandler.size.width;
		float hratio = (float)camHandler.origsize.height/(float)camHandler.size.height;

		
		int calibpointsize = 50;
		for(int i = 0;i < 4;i++) {
			ofSetColor(255, 255, 255);
			ofRect(screenoffset+camHandler.screenpoints[i].x*wratio-(calibpointsize/2), camHandler.screenpoints[i].y*hratio-(calibpointsize/2), calibpointsize, calibpointsize);
			//ofSetColor(255, 0, 0);
			//ofRect(screenoffset+camHandler.screenpoints[i].x*wratio-(calibpointsize/12), camHandler.screenpoints[i].y*hratio-(calibpointsize/12), calibpointsize/6, calibpointsize/6);
		}

	}
		
	
		
	

	
}




void testApp::keyPressed( int key ) {
    
	
	if( key == '+' ) {
		camHandler.defaultThreshold +=1;
		camHandler.threshold = camHandler.defaultThreshold;
		
	}
	else 
	if( key == '-' ) {
		camHandler.defaultThreshold -=1;
		camHandler.threshold = camHandler.defaultThreshold;
	}
	else 
	if( key == 'k' ) {
		camHandler.minBlobSize +=100;
	}
	else 
	if( key == 'l' ) {
		camHandler.minBlobSize -=100;
	}
	else 
	if( key == 'h' ) {
		camHandler.maxBlobSize +=100;
	}
	else 
	if( key == 'j' ) {
		camHandler.maxBlobSize -=100;
	}
	else 
	if( key == 'a' ) {
		camHandler.callibrate();
	}
	else 
	if( key == 'm' ) {
		camHandler.startManualCallibrate();
	}
	else 
    if( key == 's' ) {
        camHandler.vidGrabber.videoSettings();
    } 
	 
	else if( key == ' ' ) {
         camHandler.bLearnBakground = true;
	}
	else if( key == 'p' ) {
         pause = !pause;
	}
	else if( key == 'd' ) {
         drawDebugBlobs = !drawDebugBlobs;
	}
	else if( key == 'b' ) {
         drawDebugMinMaxBlobs = !drawDebugMinMaxBlobs;
	}
	// Controling debugblog
	else if( key == 'y' ) {
		debugBlob.x -= 10;
	}
	else if( key == '7' ) {
		debugBlob.y -= 10;
	}
	else if( key == 'i' ) {
		debugBlob.x += 10;
	}
	else if( key == 'u' ) {
		debugBlob.y += 10;
	}
	else if( key == '2' ) {
		startOOGame();
	}
	else if( key == '1' ) {
		startPongGame();
	}
	else if( key == 'g' ) {
		showgrid = !showgrid;
	}
	else if( key == 'f' ) {
		shakeimage = !shakeimage;
	}
	else if( key == '4' ) {
		colors.backgroundcolor = 0x888888;
		colors.foregroundcolor = 0x000000;
		colors.fillcolor = 0xaaaadd;
	}
	else if( key == '3' ) {
		colors.backgroundcolor = 0x000000;
		colors.foregroundcolor = 0xffffff;
		colors.fillcolor = 0xaaaadd;
	}

}
void testApp::mouseMoved( int x, int y ) {}
void testApp::mouseDragged( int x, int y, int button ) {}
void testApp::mousePressed( int x, int y, int button ) 
{
	if(camHandler.isManualCalibrating)
	{
		float wratio = (float)camHandler.size.width/(float)camHandler.origsize.width;
		float hratio = (float)camHandler.size.height/(float)camHandler.origsize.height;
		camHandler.calibPoints.push_back(ofPoint((x-screenoffset/2),(y-csize.height/2)));
	}
}
void testApp::mouseReleased() {}
